package com.example.autoconfig.app;

import com.example.autoconfigure.bean.Klass;
import com.example.autoconfigure.bean.School;
import com.example.autoconfigure.bean.Student;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.Collections;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * @author fangzhuangzhan
 * @date 2021/09/05 09:53
 */
@RequestMapping("/test")
@Controller
public class TestController {

    @Autowired
    private Student student;

    @Autowired
    private School school;

    @Autowired
    private Klass klass;


    @GetMapping("/auto")
    public String test(){
        System.out.println("student name = " + student.getName());
        System.out.println("klass name = " + klass.getName());
        System.out.println("school name = " + school.getName());
        return "success";
    }

    @Autowired
    private StringRedisTemplate redisTemplate;

    @GetMapping("/setV")
    @ResponseBody
    public Object setV(String key, String value){
        System.out.println("setV");
        redisTemplate.opsForValue().set(key, value);
        return redisTemplate.opsForValue().get(key);
    }


    private static final String REDIS_LOCK = "app:lock";
    private static final Long RELEASE_SUCCESS = 1L;

    /**
     * 加redis锁，成功返回锁的val
     * @return
     */
    @GetMapping("/redisLock")
    @ResponseBody
    public Object lock(){
        final ValueOperations ops = redisTemplate.opsForValue();
        String lockValue = UUID.randomUUID().toString();
        return ops.setIfAbsent(REDIS_LOCK, lockValue, 5, TimeUnit.MINUTES) ? lockValue:"null";
    }

    /**
     * 通过上面返回的锁val，通过lua脚本，删除对应自己的锁
     * @param key
     * @param val
     * @return
     */
    @GetMapping("/releaseRedisLock")
    @ResponseBody
    public Object lock(String key,String val){
        String script = "if redis.call('get',KEYS[1]) == ARGV[1] then return redis.call('del',KEYS[1]) else return 0 end";
        DefaultRedisScript<Long> redisScript = new DefaultRedisScript<>(script, Long.class);
        Long result = redisTemplate.execute(redisScript, Collections.singletonList(key), val);
        return RELEASE_SUCCESS.equals(result);
    }

    /**
     * 设置库存10件，decr操作 >= 0即秒杀成功，否则秒杀失败
     * @param key
     * @return
     */
    @GetMapping("/seckill")
    @ResponseBody
    public Object lock(String key){
        final ValueOperations<String, String> stringStringValueOperations = redisTemplate.opsForValue();
        final Long decrement = stringStringValueOperations.decrement(key);
        return decrement != null && decrement >= 0 ? "秒杀成功":"秒杀失败";
    }







}
